#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>

class Profile {
private:
    int id;
    std::string email;
public:
    Profile(int id_, std::string email_)
    :id(id_), email(email_)
    {
    }
    int getID() const
    {
        return id;
    }
    std::string getEmail()
    {
        return email;
    }
    bool operator==(const Profile &p) const //注意这里的两个const
    {
        return (id == p.id) ;
    }
    void print()
    {
        std::cout<<"ID: "<<id<<" Email: "<<email<<std::endl;
    }
};

struct myHashFuc
{
    std::size_t operator()(const Profile &key) const
    {
        return std::hash<int>()(key.getID());
    }
};

class ProfileIterator
{
public:
    virtual Profile getNext() = 0;
    virtual bool hasMore() = 0;
};

class SocialNetwork
{
public:
    virtual  ProfileIterator* createFriendsIterator()= 0;
    virtual  ProfileIterator* createCoworkersIterator() = 0;
};
enum class
ProfileType
{
    Friend,
    Coworker,
    FriendCoworker
};
class WeChatIterator;
class WeChat
{
private:
    std::unordered_map<Profile, ProfileType, myHashFuc> map;
public:
    WeChat()
    {
    }
    void addProfile(int id, std::string email, ProfileType type)
    {
        addProfile(Profile(id, email), type);
    }
    void addProfile(Profile profile, ProfileType type)
    {
        if(map.find(profile) == map.end())
        {
            map[profile] = type;
        }else{
            ProfileType nowType = map[profile];
            if(nowType == ProfileType::Friend && type == ProfileType::Coworker)
            {
                map[profile] = ProfileType::FriendCoworker;
            }
            if(nowType == ProfileType::Coworker && type == ProfileType::Friend)
            {
                map[profile] = ProfileType::FriendCoworker;
            }
        }
    }
    std::vector<Profile> socialGraphRequest(ProfileType type)
    {
        std::vector<Profile> ret;
        for(auto iter = map.begin(); iter != map.end(); ++iter)
        {
            if(iter->second == type || iter->second == ProfileType::FriendCoworker)
            {
                ret.push_back(iter->first);
            }
        }
        return ret;
    }
    ProfileIterator* createFriendsIterator();
    ProfileIterator* createCoworkersIterator();
};

class WeChatIterator : public ProfileIterator
{
private:
    WeChat* wetChat = nullptr;
    int cur;
    std::vector<Profile> profilelist;
    ProfileType type;
public:
    WeChatIterator(WeChat* weChat_, ProfileType type_)
    {
        wetChat = weChat_;
        type = type_;
        profilelist = wetChat->socialGraphRequest(type);
        cur = -1;
    }
    Profile getNext()
    {
        ++cur;
        return profilelist[cur];
    }
    bool hasMore()
    {
        return cur != profilelist.size() - 1;
    }
};
ProfileIterator* WeChat::createFriendsIterator()
{
    return new WeChatIterator(this, ProfileType::Friend);
}
ProfileIterator* WeChat::createCoworkersIterator()
{
    return new WeChatIterator(this, ProfileType::Coworker);
}
int main() {
    WeChat weChat;
    weChat.addProfile(1, "email1", ProfileType::Friend);
    weChat.addProfile(2, "email2", ProfileType::Friend);
    weChat.addProfile(3, "email3", ProfileType::Friend);
    weChat.addProfile(4, "email4", ProfileType::Friend);
    weChat.addProfile(5, "email5", ProfileType::Friend);
    weChat.addProfile(6, "email6", ProfileType::Friend);
    weChat.addProfile(7, "email7", ProfileType::Friend);
    weChat.addProfile(8, "email8", ProfileType::Friend);
    weChat.addProfile(9, "email9", ProfileType::Friend);

    weChat.addProfile(2, "email1", ProfileType::Coworker);
    weChat.addProfile(4, "email2", ProfileType::Coworker);
    weChat.addProfile(6, "email3", ProfileType::Coworker);
    weChat.addProfile(8, "email4", ProfileType::Coworker);
    weChat.addProfile(10, "email5", ProfileType::Coworker);
    weChat.addProfile(12, "email6", ProfileType::Coworker);
    weChat.addProfile(14, "email7", ProfileType::Coworker);
    weChat.addProfile(16, "email8", ProfileType::Coworker);
    weChat.addProfile(18, "email9", ProfileType::Coworker);
    ProfileIterator* iterator = weChat.createFriendsIterator();
    while(iterator->hasMore())
    {
        Profile profile = iterator->getNext();
        profile.print();
    }
    return 0;
}